    /* chimaera_messager-table.c : store the message content
 *
 * ====================================================================
 * Copyright (c) 2008-2009 Chimaera team.  All rights reserved.
 *
 *
 * @author kkndyu
 * @mail kkndyu@gmail.com
 * ====================================================================
 */

#include "bdb_compat.h"
#include "svn_fs.h"
#include "svn_pools.h"
#include "../fs.h"
#include "../err.h"
#include "../util/skel.h"
#include "../util/fs_skels.h"
#include "../../libsvn_fs/fs-loader.h"
#include "bdb-err.h"
#include "dbt.h"
#include "rev-table.h"
#include "../trail.h"

#include "svn_private_config.h"
#include "private/svn_fs_util.h"

#include "chimaera_message-table.h"


/* Opening/creating the `chimaera_user' table.  */

int svn_fs_bdb__open_chimaera_message_table(DB **chimaeramessage_p,
                                     DB_ENV *env,
                                     svn_boolean_t create)
{
  const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
  DB *chimaera_message;

  BDB_ERR(svn_fs_bdb__check_version());
  BDB_ERR(db_create(&chimaera_message, env, 0));
  BDB_ERR((chimaera_message->open)(SVN_BDB_OPEN_PARAMS(chimaera_message, NULL),
								"chimaera_message", 0, DB_RECNO,
								open_flags, 0666));

  *chimaeramessage_p = chimaera_message;
  return 0;
}



/* Storing and retrieving filesystem revisions.  */


svn_error_t *
svn_fs_bdb__get_chimaera_message(chimaeramessage_t *chimaeramessage_p,
							  svn_fs_t *fs, apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  int db_err;
  DBT key, value;
  skel_t *skel;
  db_recno_t recno = chimaeramessage_p->message_id;

  if (SVN_IS_VALID_REVNUM(chimaeramessage_p->message_id))
  {
	  db_err = bfd->chimaera_message->get(bfd->chimaera_message, NULL,
		  svn_fs_base__set_dbt(&key, &recno,
		  sizeof(recno)),
		  svn_fs_base__result_dbt(&value),
		  0);
  }
  svn_fs_base__track_dbt(&value, pool);

  /* If there's no such node, return an appropriately specific error.  */
  if (db_err == DB_NOTFOUND)
	  return svn_error_createf
	  (SVN_ERR_FS_NO_SUCH_REPRESENTATION, 0,
	  _("No such chimaeramessage '%s'"), key);

  /* Parse the chimaerauser skel.  */
  skel = svn_fs_base__parse_skel(value.data, value.size, pool);

  /* Convert to a native type.  */
  SVN_ERR(svn_fs_base__parse_chimaeramessage_skel(chimaeramessage_p, skel, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_bdb__put_chimaera_message(chimaeramessage_t *chimaeramessage_p,
							  svn_fs_t *fs, DB_TXN *txn,apr_pool_t *pool)
{
  base_fs_data_t *bfd = fs->fsap_data;
  int db_err;
  db_recno_t recno = 0;
  skel_t *skel;
  DBT key, value;

  /* think of if really need to use the svn fs_skels to store the message 
  * er, I'm thinking ... before I can make a decision, just use it
  */

  /* Convert from native type to skel. */
  SVN_ERR(svn_fs_base__unparse_chimaeramessage_skel(&skel, chimaeramessage_p, pool));

  if (SVN_IS_VALID_REVNUM(chimaeramessage_p->message_id))
  {
	  DBT query, result;

	  /* Update the filesystem revision with the new skel. */
	  recno = chimaeramessage_p->message_id;

	  db_err = bfd->chimaera_message->put
		  (bfd->chimaera_message, txn,
		  svn_fs_base__set_dbt(&query, &recno, sizeof(recno)),
		  svn_fs_base__skel_to_dbt(&result, skel, pool), 0);
	  return BDB_WRAP(fs, "updating filesystem revision", db_err);
  }

  //svn_fs_base__trail_debug(trail, "revisions", "put");

  db_err = bfd->chimaera_message->put(bfd->chimaera_message, txn,
	  svn_fs_base__recno_dbt(&key, &recno),
	  svn_fs_base__skel_to_dbt(&value, skel, pool),
	  DB_APPEND);
  SVN_ERR(BDB_WRAP(fs, "storing filesystem revision", db_err));

  /* if new insert, return the recno.  */
  chimaeramessage_p->message_id = recno;
  return SVN_NO_ERROR;
}
